﻿using Microsoft.Xna.Framework;
using MoLingOverhaul.Common.Cores.Data;
using MoLingOverhaul.Common.Cores.Enum;
using MoLingOverhaul.Common.UI;
using System.Collections.Generic;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
using Terraria.ModLoader.IO;
using Terraria.UI;

namespace MoLingOverhaul.Common.Systems
{
    public class SeasonSystem : ModSystem
    {      
        public static SeasonSystem Instance;
        internal UserInterface SeasonInterface;
        internal SeasonUI SeasonState;
        private GameTime _lastUpdateUiGameTime;
        public static bool ShowSeasonUI = true;
        public SeasonData CurrentSeason;      
        public override void Load()
        {
            Instance = this;
            CurrentSeason = new SeasonData();
            CurrentSeason.OnSeasonChanged += OnSeasonChanged;
            On_Main.UpdateTime += OnUpdateTime;
            if (!Main.dedServ)
            {
                SeasonState = new SeasonUI();
                SeasonState.Activate();
                SeasonInterface = new UserInterface();
                SeasonInterface.SetState(SeasonState);
            }
        }

        private void OnUpdateTime(On_Main.orig_UpdateTime orig)
        {
            orig();
            if (Main.dayTime && Main.time == 0)
            {
                CurrentSeason.UpdateSeason();
                if (Main.netMode == NetmodeID.Server)
                {
                    ModPacket packet = MoLingOverhaul.Instance.GetPacket();
                    packet.Write((byte)SeasonMessageType.SyncSeasonData);
                    packet.Write(CurrentSeason.TotalDays);
                    packet.Write((int)CurrentSeason.CurrentSeason);
                    packet.Write(CurrentSeason.DaysInCurrentSeason);
                    packet.Send();
                }
            }
        }
        public override void Unload()
        {
            Instance = null;
            SeasonState = null;
            SeasonInterface = null;
            CurrentSeason = null;
            On_Main.UpdateTime -= OnUpdateTime;
        }      
        private void OnSeasonChanged(Season newSeason)
        {
            if (Main.netMode != NetmodeID.Server)
            {
                if (Main.netMode == NetmodeID.MultiplayerClient)
                {
                    ModPacket packet = Mod.GetPacket();
                    packet.Write((byte)SeasonMessageType.RequestSeasonData);
                    packet.Send();
                }
            }
        }
        public override void UpdateUI(GameTime gameTime)
        {
            _lastUpdateUiGameTime = gameTime;
            if (SeasonInterface?.CurrentState != null && ShowSeasonUI)
            {
                SeasonInterface.Update(gameTime);
            }
        }
        public override void ModifyInterfaceLayers(List<GameInterfaceLayer> layers)
        {
            int mouseTextIndex = layers.FindIndex(layer => layer.Name.Equals("Vanilla: Inventory"));
            if (mouseTextIndex != -1)
            {
                layers.Insert(mouseTextIndex, new LegacyGameInterfaceLayer(
                    "MoLingOverhaul: Season UI",
                    delegate
                    {
                        if (_lastUpdateUiGameTime != null && SeasonInterface?.CurrentState != null && ShowSeasonUI)
                        {
                            SeasonInterface.Draw(Main.spriteBatch, _lastUpdateUiGameTime);
                        }
                        return true;
                    },
                    InterfaceScaleType.UI)
                );
            }
        }
        public override void SaveWorldData(TagCompound tag)
        {
            if (CurrentSeason != null)
            {
                tag["SeasonSystem_TotalDays"] = CurrentSeason.TotalDays;
                tag["SeasonSystem_CurrentSeason"] = (int)CurrentSeason.CurrentSeason;
                tag["SeasonSystem_DaysInCurrentSeason"] = CurrentSeason.DaysInCurrentSeason;
            }
        }
        public override void LoadWorldData(TagCompound tag)
        {
            if (tag.ContainsKey("SeasonSystem_TotalDays"))
            {
                CurrentSeason.TotalDays = tag.GetInt("SeasonSystem_TotalDays");
                CurrentSeason.CurrentSeason = (Season)tag.GetInt("SeasonSystem_CurrentSeason");
                CurrentSeason.DaysInCurrentSeason = tag.GetInt("SeasonSystem_DaysInCurrentSeason");
            }
            else
            {
                CurrentSeason.TotalDays = 0;
                CurrentSeason.CurrentSeason = Season.Spring;
                CurrentSeason.DaysInCurrentSeason = 0;
            }
        }
        public override void OnWorldLoad()
        {
            if (Main.netMode == NetmodeID.MultiplayerClient && CurrentSeason != null)
            {
                ModPacket packet = Mod.GetPacket();
                packet.Write((byte)SeasonMessageType.RequestSeasonData);
                packet.Send();
            }
        }
    }
}